﻿$import( "SmitearWebGL.Resources.Texture" );
$import( "SmitearWebGL.Events.ResourceEvent" );

SmitearWebGL.Resources.TextureCube = SmitearWebGL.Resources.Texture.extend(
{
	/******** constructor ********/

	init : function()
	{
		this._super();
		this._registClass( "SmitearWebGL.Resources.TextureCube" );

		this._glTextureTarget = null;
		this._urls = null;
		this._faceFlag = null;
	}
	,
	load : function( fileName )
	{
		$THROW( this.isResourceCreated(), "该资源还没有被创建." );
		
		this.urls = fileName.split(",");
		if ( this.urls.length == 1 )
		{
			var bitmap = this.context.resourceManager.createResource( "bitmap_" + fileName, SmitearWebGL.Resources.Bitmap );
			bitmap.addEventListener( SmitearWebGL.Resources.Bitmap.LOAD_COMPLETE, this, this._loadCompleteHandler2);
			bitmap.load( fileName );
		}
		else
		{
			$THROW( this.urls.length >= 6, "加载CubeMap失败" );
			this._faceFlag.set( ( 2 << SmitearWebGL.Resources.TextureCube.NUM_FACES) - 1 );
			this._loadFaceBitmap( 0 );
		}
	}
	,
	drawImage : function( source_img, source_mip, dest_mip,
					source_x, source_y,
					source_width, source_height,
					dest_x, dest_y,
					dest_width, dest_height,
					face )
	{
		this._super( source_img._canvas, source_mip, dest_mip,
					source_x, source_y,
					source_width, source_height,
					dest_x, dest_y,
					dest_width, dest_height, face );
	}
	,
	
	/******** private method ********/
	
	_loadCompleteHandler : function( e )
	{
		var face = this._faceFlag.highestBit();
		
		var bitmap = e.sender;
		bitmap.removeEventListener( SmitearWebGL.Resources.Bitmap.LOAD_COMPLETE, this._loadCompleteHandler );
		
		this.setFromBitmap( bitmap, face );
		
		if ( ++ face < SmitearWebGL.Resources.TextureCube.NUM_FACES )
			this._loadFaceBitmap( face );
		else
		{
			this.dispatchEvent( new SmitearWebGL.Events.Event( SmitearWebGL.Resources.Texture.LOAD_COMPLETE ) );
		}
	}
	,
	_loadFaceBitmap : function( face )
	{
		this._faceFlag.setBit( face, true );
		var bitmap = g_bitmapManager.createResource( "bitmap_" + this.urls[face] );
		bitmap.addEventListener( SmitearWebGL.Resources.Bitmap.LOAD_COMPLETE, this, this._loadCompleteHandler);
		bitmap.load( this.urls[face] );
	}
	,
	_loadCompleteHandler2 : function( e )
	{
		var bitmap = e.sender;
		bitmap.removeEventListener( SmitearWebGL.Resources.Bitmap.LOAD_COMPLETE, this._loadCompleteHandler2 );
		bitmap.rotate( 90 );
		var canvas = bitmap.getCanvas();
		this._cutBitmapToFaces( canvas, SmitearWebGL.Resources.TextureCube.FACE_POSITIVE_X );
		this._cutBitmapToFaces( canvas, SmitearWebGL.Resources.TextureCube.FACE_NEGATIVE_X );
		this._cutBitmapToFaces( canvas, SmitearWebGL.Resources.TextureCube.FACE_POSITIVE_Y );
		this._cutBitmapToFaces( canvas, SmitearWebGL.Resources.TextureCube.FACE_NEGATIVE_Y );
		this._cutBitmapToFaces( canvas, SmitearWebGL.Resources.TextureCube.FACE_POSITIVE_Z );
		this._cutBitmapToFaces( canvas, SmitearWebGL.Resources.TextureCube.FACE_NEGATIVE_Z );
		
		this.dispatchEvent( new SmitearWebGL.Events.Event( SmitearWebGL.Resources.Texture.LOAD_COMPLETE ) );
	}
	,
	_cutBitmapToFaces : function( canvas, face )
	{
		var quarterWidth = canvas.width / 3;
		var quarterHeight = canvas.height / 4;
		var sx, sy, flip = false;
		
		switch ( face )
		{
			case SmitearWebGL.Resources.TextureCube.FACE_POSITIVE_X : 
				sx = quarterWidth * 2.0;
				sy = quarterHeight;
				break;
				
			case SmitearWebGL.Resources.TextureCube.FACE_NEGATIVE_X : 
				sx = 0;
				sy = quarterHeight;
				break;
				
			case SmitearWebGL.Resources.TextureCube.FACE_POSITIVE_Y : 
				sx = quarterWidth;
				sy = 0;
				flip = true;
				break;
				
			case SmitearWebGL.Resources.TextureCube.FACE_NEGATIVE_Y : 
				sx = quarterWidth;
				sy = quarterHeight * 2.0;
				flip = true;
				break;
				
			case SmitearWebGL.Resources.TextureCube.FACE_POSITIVE_Z : 
				sx = quarterWidth;
				sy = quarterHeight * 3.0;
				flip = true;
				break;
				
			case SmitearWebGL.Resources.TextureCube.FACE_NEGATIVE_Z : 
				sx = quarterWidth;
				sy = quarterHeight;
				break;
		}
		
		//right
		var temp_canvas = document.createElement("canvas");
		temp_canvas.width = quarterWidth;
		temp_canvas.height = quarterHeight;
		
		var context = temp_canvas.getContext( '2d' );
		
		switch ( face )
		{
			case SmitearWebGL.Resources.TextureCube.FACE_POSITIVE_X : 
			case SmitearWebGL.Resources.TextureCube.FACE_NEGATIVE_X : 
			case SmitearWebGL.Resources.TextureCube.FACE_NEGATIVE_Z : 
				context.translate( quarterWidth, 0 );
				context.scale( -1, 1 );
				break;
		}
		
		context.drawImage( canvas, sx, sy, quarterWidth, quarterHeight, 0, 0, quarterWidth, quarterHeight );
		this.setFromCanvas( temp_canvas, flip, face, 0 );
		
		this._texWidth = canvas.width;
		this._texHeight = canvas.height;
	}
	,
	
	/******** inherit method ********/
	
	_createResource : function()
	{
		this._super();

		this._glTextureTarget = this.context.gl.TEXTURE_CUBE_MAP;
		this._urls = [];
		this._faceFlag = new SmitearWebGL.Core.Math.BitFlags();
	}
	,
	_destroyResource : function()
	{
		this._super();
		
		this._renderSurfaces.splice( 0, this._renderSurfaces.length );
		this._renderSurfaces = null;
	}
}
);

SmitearWebGL.Resources.TextureCube.FACE_POSITIVE_X = 0;	//right
SmitearWebGL.Resources.TextureCube.FACE_NEGATIVE_X = 1;
SmitearWebGL.Resources.TextureCube.FACE_POSITIVE_Y = 2;	//botom
SmitearWebGL.Resources.TextureCube.FACE_NEGATIVE_Y = 3;
SmitearWebGL.Resources.TextureCube.FACE_POSITIVE_Z = 4;	//front
SmitearWebGL.Resources.TextureCube.FACE_NEGATIVE_Z = 5;
SmitearWebGL.Resources.TextureCube.NUM_FACES = 6;